package cn.myframe.utils;

import com.google.common.base.Strings;
import org.apache.commons.lang.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.Security;

public class AESCode {

	
	private static final String KEY_ALGORITHM = "AES";
	public static final String CIPHER_ALGORITHM="AES/ECB/PKCS7Padding"; 
	public static String SHAREDKEY = "F97CA1C836F5200625619A25576C16A1C9E6B87B9A2784230C309F39E9999E65";
	
	private static boolean init = false;
	
	private static String byte2HexString ( byte[] data ) {
        String result = "" ;
        for ( int i = 0 ; i < data.length ; i++ ) {
            result += Integer.toString ( ( data[ i ] & 0xff ) + 0x100 , 16 ).substring ( 1 ).toUpperCase () ;
        }
        return result ;
    }

    private static byte[] String2Bytes(String str){
        byte[] res = str.getBytes();
        byte[] data = new byte[res.length/2];
        for ( int i = 0 ; i < (res.length/2) ; i++) {
            data[i] = Integer.valueOf(str.substring(i*2,(i*2)+2),16).byteValue();
        }
        return data;
    }
	
	public static String initSecretKey(){
		initProvider();
		KeyGenerator kg = null;
		try {
			kg = KeyGenerator.getInstance(KEY_ALGORITHM, "BC");
		} catch (Exception e) {
			return null;
		}
		kg.init(256);
		SecretKey secretKey = kg.generateKey();
		return byte2HexString(secretKey.getEncoded());
	}
	
	public static Key toKey(byte[] key) throws Exception{  
        SecretKey secretKey=new SecretKeySpec(key,KEY_ALGORITHM);  
        return secretKey;  
    }  
	
	public static String encrypt(String data,String key) throws Exception{  
		initProvider();
        Key k=toKey(String2Bytes(key));  
        Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM, "BC");  
        cipher.init(Cipher.ENCRYPT_MODE, k); 
        byte[] cipherData = cipher.doFinal(data.getBytes());
        return  byte2HexString(cipherData);
    }
	
	public static String encrypt(String data) throws Exception{  
		initProvider();
        Key k=toKey(String2Bytes(SHAREDKEY));  
        Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM, "BC");  
        cipher.init(Cipher.ENCRYPT_MODE, k); 
        byte[] cipherData = cipher.doFinal(data.getBytes());
        return  byte2HexString(cipherData);
    }

	public static String decrypt(String data, String key) throws Exception {
		initProvider();
        Key k=toKey(String2Bytes(key));
		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
		cipher.init(Cipher.DECRYPT_MODE, k);
		byte[] cipherData = cipher.doFinal(String2Bytes(data));
		return new String(cipherData);
	}
	
	
	public static String decrypt(String data){
		try {
			if(StringUtils.isNotEmpty(data)){
				return decrypt(data,SHAREDKEY);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
		
	}
	
	private static void initProvider(){
		if(init){
			return;
		}
		Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
		try {
			String sharedKey = SHAREDKEY;
			if(!Strings.isNullOrEmpty(sharedKey)){
				SHAREDKEY = sharedKey;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		init = true;
	}
	
	public static void main(String[] args) {
//		String key = AESCode.initSecretKey();
		String key = "F97CA1C836F5200625619A25576C16A1C9E6B87B9A2784230C309F39E9999E65";
		String srcData = "root";
		System.out.println("key:"+key);
		System.out.println("src:"+srcData);
		try {
			String encoderStr = AESCode.encrypt(srcData, key);
			System.out.println("encoder str:"+encoderStr);
			System.out.println("decoder str:"+AESCode.decrypt("FF453E8B9EB17AF678FE1B03B83F067F", key));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
